#include "OpenGLHelper.h"
#include <iostream>

namespace OGLHelper{

void ColorFromColormap(float &r, float &g, float &b, unsigned int index)
{
    index = index >= 64 ? 64 : index;

    r = colormap[index * 3];
    g = colormap[index * 3 + 1];
    b = colormap[index * 3 + 2];
}

void DrawBackground(float topR, float topG, float topB, float buttomR, float buttomG, float buttomB)
{
    if(!bgList)
    {
        bgList = glGenLists(1);
        glNewList(bgList, GL_COMPILE);

        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
        glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 10000);

        glPushAttrib(GL_ALL_ATTRIB_BITS);
        glDisable(GL_CULL_FACE);
        glDisable(GL_LIGHTING);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_TEXTURE_2D);

        glBegin(GL_QUADS);
        glColor3f(topR, topG, topB);
        glVertex2d(1.0, 1.0);
        glColor3f(topR, topG, topB);
        glVertex2d(-1.0, 1.0);
        glColor3f(buttomR, buttomG, buttomB);
        glVertex2d(-1.0, -1.0);
        glColor3f(buttomR, buttomG, buttomB);
        glVertex2d(1.0, -1.0);
        glEnd();

        glPopAttrib();

        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);

        glEndList();
        glCallList(bgList);
    }
    else
        glCallList(bgList);
}

bool HitObject(int winX, int winY, double *retX, double *retY, double *retZ)
{
    bool flag = false;
    GLint viewport[4] = {0};
    GLdouble modelviewMatrix[16] = {0};
    GLdouble projMatrix[16] = {0};

    glGetIntegerv(GL_VIEWPORT, viewport);
    glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix);
    glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);

    GLint x = winX;
    GLint y = viewport[3] - (GLint)winY - 1;

    float zVal = 0;
    //get z value under the cursor
    glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zVal);

    GLubyte stencilVal = 0;
    //get stencil value, 1 represents hit, 0 represents miss
    glReadPixels(x, y, 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &stencilVal);

    if(stencilVal == 1)
    {
        flag = true;
        GLdouble objX = 0, objY = 0, objZ = 0, objW = 0;
        flag = gluUnProject((GLdouble)x, (GLdouble)y, (GLdouble)zVal, modelviewMatrix, projMatrix, viewport, &objX, &objY, &objZ);

        if(retX)
            *retX = objX;
        if(retY)
            *retY = objY;
        if(retZ)
            *retZ = objZ;
    }

    return flag;
}

}
